<template>
  <div
    class="slider__button-wrapper"
    :style="{left: currentPosition}"
    @touchstart="onButtonDown"
    @touchend="handleMouseLeave"
    @mouseenter="handleMouseEnter"
    @mousedown="onButtonDown"
    @mouseleave="handleMouseLeave">
    <div
      class="slider__button"
      :class="{'hover': hovering, 'drag': dragging}"
      :style="{
        backgroundColor: buttonColor,
        boxShadow: buttonShadow && (hovering || dragging) ? 'rgba(0, 0, 0, 0.12) 3px 3px 8px 3px' : ''
      }"
      >
      <img
        v-if="isloading"
        class="loading"
        src="../../../../assets/images/player_loading.gif" />
    </div>
  </div>
</template>

<script lang="ts">
import Vue from 'vue'

export default Vue.extend({
  name: 'SliderButton',

  data () {
    return {
      parent: {},
      hovering: false,
      dragging: false,
      startX: 0,
      startPosition: 0,
      currentX: 0,
      newPosition: 0
    }
  },

  props: {
    value: {
      type: Number,
      default: 0
    },
    isloading: {
      type: Boolean,
      default: false
    }
  },

  computed: {
    disabled ():boolean {
      const parent:any = this.$parent
      return parent.disabled
    },

    max ():number {
      const parent:any = this.$parent
      return parent.max
    },

    min ():number {
      const parent:any = this.$parent
      return parent.min
    },

    step ():number {
      const parent:any = this.$parent
      return parent.step
    },

    precision ():number {
      const parent:any = this.$parent
      return parent.precision
    },

    currentPosition ():string {
      return `${(this.value - this.min) / (this.max - this.min) * 100}%`
    },

    buttonColor ():string {
      const parent:any = this.$parent
      return parent.buttonColor
    },

    buttonShadow ():string {
      const parent:any = this.$parent
      return parent.buttonShadow
    }
  },

  methods: {
    handleMouseEnter () {
      this.hovering = true
    },
    onButtonDown (event:any) {
      this.dragging = true
      this.onDragStart(event)
      window.addEventListener('touchmove', this.onDragging)
      window.addEventListener('touchend', this.onDragEnd)
      window.addEventListener('mousemove', this.onDragging)
      window.addEventListener('mouseup', this.onDragEnd)
      window.addEventListener('contextmenu', this.onDragEnd)
    },
    handleMouseLeave () {
      this.hovering = false
    },
    onDragStart (event:any) {
      this.startX = event.clientX || event.touches[0].clientX
      this.startPosition = parseInt(this.currentPosition, 10)
    },
    onDragging (event:any) {
      const parent:any = this.$parent
      this.currentX = event.clientX || event.touches[0].clientX
      const diff = (this.currentX - this.startX) / parent.$sliderWidth * 100
      this.newPosition = this.startPosition + diff
      this.setPosition(this.newPosition)
    },
    onDragEnd () {
      const parent:any = this.$parent
      this.dragging = false
      window.removeEventListener('touchmove', this.onDragging)
      window.removeEventListener('touchend', this.onDragEnd)
      window.removeEventListener('mousemove', this.onDragging)
      window.removeEventListener('mouseup', this.onDragEnd)
      window.removeEventListener('contextmenu', this.onDragEnd)
      console.log('onDragEnd')
      parent.setValue()
    },
    setPosition (newPosition:number) {
      if (newPosition < 0) {
        newPosition = 0
      } else if (newPosition > 100) {
        newPosition = 100
      }
      const lengthPerStep = 100 / ((this.max - this.min) / this.step)
      const steps = Math.round(newPosition / lengthPerStep)
      let value = steps * lengthPerStep * (this.max - this.min) * 0.01 + this.min
      value = parseFloat(value.toFixed(this.precision))
      this.$emit('input', value)
    }
  }
})
</script>

<style scoped>

.slider__button-wrapper {
  width: 36px;
  height: 36px;
  position: absolute;
  z-index: 1001;
  top: -16px;
  transform: translateX(-50%);
  background-color: transparent;
  text-align: center;
}
.slider__button-wrapper:hover {
  cursor: -webkit-grab;
  cursor: grab;
}
.slider__button-wrapper:after {
  display: inline-block;
  content: '';
  height: 100%;
  vertical-align: middle;
}
.slider__button {
  position: relative;
  width: 12px;
  height: 12px;
  border-radius: 50%;
  transition: .2s;
  vertical-align: middle;
  display: inline-block;
}
.slider__button.hover,
.slider__button.drag {
  transform: scale(1.5);
}
.loading {
  width: 75%;
  height: 75%;
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}
</style>
